﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;

namespace OpGen.Extensions.Network
{
    /// <summary>
    /// Stellt einen Byte Buffer dar, der zum Senden und Empfangen von Netzwerkdaten dient.
    /// </summary>
    internal class BufferStream
    {
        private MemoryStream _stream;

        /// <summary>
        /// Erstellt einen neue Instanz der BufferStream-Klasse
        /// </summary>
        public BufferStream()
        {
            _stream = new MemoryStream(0);
        }

        /// <summary>
        /// Liefert die Aktuelle Länge der Daten
        /// </summary>
        public int CurrentLength
        {
            get { return (int)_stream.Position; }
        }

        /// <summary>
        /// Liefert die Gesamtlänge der Daten
        /// </summary>
        public int TotalLength
        {
            get { return (int)_stream.Length; }
        }

        /// <summary>
        /// Gibt an ob die Daten komplett sind
        /// </summary>
        public bool IsComplet
        {
            get { return _stream.Position == _stream.Length; }
        }

        /// <summary>
        /// Gibt an ob der Buffer zurückgesetzt wurde
        /// </summary>
        public bool IsClean
        {
            get { return _stream.Position == 0 & _stream.Length == 0; }
        }

        /// <summary>
        /// Setzt den Buffer zurück
        /// </summary>
        public void Clear()
        {
            _stream.Position = 0;
            _stream.SetLength(0);
        }

        /// <summary>
        /// Startet einen neuen Empfangsbuffer
        /// </summary>
        /// <param name="buffer">Das Byte-Array das die Daten enthält</param>
        /// <param name="offset">Der Offset des Buffers an dem das kopieren beginnt</param>
        /// <param name="count">Die Anzahl der Datenim Buffer die kopiert werden sollen</param>
        /// <param name="totalLength">Die Gesamtlänge der zu empfangenen Daten</param>
        public void Begin(byte[] buffer, int offset, int count,int totalLength)
        {
            _stream.SetLength(totalLength);
            _stream.Write(buffer, offset, count - offset);
        }

        /// <summary>
        /// Fügt dem Buffer die angegebenen Daten an
        /// </summary>
        /// <param name="buffer">Das Byte-Array das die Daten enthält</param>
        /// <param name="offset">Der Offset des Buffers an dem das kopieren beginnt</param>
        /// <param name="count">Die Anzahl der Datenim Buffer die kopiert werden sollen</param>
        public void Append(byte[] buffer, int offset, int count)
        {
            _stream.Write(buffer, offset, count);
        }

        /// <summary>
        /// Liefert die Bufferdaten als Byte-Array zurück
        /// </summary>
        /// <returns></returns>
        public byte[] ToArray()
        {
            return _stream.ToArray();
        }
    }
}
